package com.avoscloud.chat.service.emoji;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ImageSpan;

import com.avoscloud.chat.base.App;
import com.avoscloud.chat.util.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 把文本内容转换为图像，实现输入框图文并茂的效果
 */
public class EmotionUtils {
	public static List<List<String>> emojiGroups;
	private static final int ONE_PAGE_SIZE = 21;
	private static Pattern pattern;
	private static String[] emojiCodes = new String[] { ":smile:",
			":laughing:", ":blush:", ":smiley:", ":relaxed:", ":smirk:",
			":heart_eyes:", ":kissing_heart:", ":kissing_closed_eyes:",
			":flushed:", ":relieved:", ":satisfied:", ":grin:", ":wink:",
			":stuck_out_tongue_winking_eye:", ":stuck_out_tongue_closed_eyes:",
			":grinning:", ":kissing:", ":kissing_smiling_eyes:",
			":stuck_out_tongue:", ":sleeping:", ":worried:", ":frowning:",
			":anguished:", ":open_mouth:", ":grimacing:", ":confused:",
			":hushed:", ":expressionless:", ":unamused:", ":sweat_smile:",
			":sweat:", ":disappointed_relieved:", ":weary:", ":pensive:",
			":disappointed:", ":confounded:", ":fearful:", ":cold_sweat:",
			":persevere:", ":cry:", ":sob:", ":joy:", ":astonished:",
			":scream:", ":tired_face:", ":angry:", ":rage:", ":triumph:",
			":sleepy:", ":yum:", ":mask:", ":sunglasses:", ":dizzy_face:",
			":neutral_face:", ":no_mouth:", ":innocent:", ":thumbsup:",
			":thumbsdown:", ":clap:", ":point_right:", ":point_left:" };

	static {
		// 计算表情显示所需页数
		int pages = emojiCodes.length / ONE_PAGE_SIZE
				+ (emojiCodes.length % ONE_PAGE_SIZE == 0 ? 0 : 1);
		emojiGroups = new ArrayList<List<String>>();
		for (int page = 0; page < pages; page++) {
			List<String> onePageEmojis = new ArrayList<String>();// 存放一页表情的list
			int start = page * ONE_PAGE_SIZE;// 每一页开始表情的序号
			int end = Math.min(page * ONE_PAGE_SIZE + ONE_PAGE_SIZE,
					emojiCodes.length);// 每一页结束表情的序号
			for (int i = start; i < end; i++) {
				onePageEmojis.add(emojiCodes[i]);// 根据序号将表情加入onePageEmojis
			}
			emojiGroups.add(onePageEmojis);
		}
		// 匹配正则表达式，使用Pattern的compile进行编译，返回实例pattern,该实例即代表正则表达式
		pattern = Pattern.compile("\\:[a-z0-9-_]*\\:");
	}

	public static boolean contain(String[] strings, String string) {
		for (String s : strings) {
			if (s.equals(string)) {
				return true;
			}
		}
		return false;
	}

	/*
	 * CharSequence抽象类接口，不能用new来创建实例
	 */
	public static CharSequence replace(Context ctx, String text) {
		if (TextUtils.isEmpty(text)) {
			return text;
		}
		SpannableString spannableString = new SpannableString(text);// 用SpannableString来实现richText富媒体消息
		// 使用pattern的matcher方法返回一个Matcher的实例，符合正则表达式。
		Matcher matcher = pattern.matcher(text);
		while (matcher.find()) {// find方法表示是否有符合的字符串
			String factText = matcher.group();// group方法将符合的字符串返回
			String key = factText.substring(1, factText.length() - 1);// 去掉首尾符号
			if (contain(emojiCodes, factText)) {
				Bitmap bitmap = getEmojiDrawable(ctx, key);
				ImageSpan image = new ImageSpan(ctx, bitmap);//创建ImageSpan对象，封装图像，以便插入spannableString
				int start = matcher.start();//获得起始位置
				int end = matcher.end();//获得结束位置
				// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE表示不包含两端start和end所在的端点，将start和end之间的文本格式设置成图片格式
				spannableString.setSpan(image, start, end,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
		}
		return spannableString;
	}

	// 若资源库中并不存在这个名字的表情则打印出错误信息
	public static void isEmojiDrawableAvailable() {
		for (String emojiCode : emojiCodes) {
			String code = emojiCode.substring(1, emojiCode.length() - 1);
			Bitmap bitmap = getDrawableByName(App.ctx, code);
			if (bitmap == null) {
				Logger.d("not available test " + code);
			}
		}
	}

	// 根据资源名字去资源库中获取表情
	public static Bitmap getEmojiDrawable(Context context, String name) {
		return getDrawableByName(context, "emoji_" + name);
	}

	public static Bitmap getDrawableByName(Context ctx, String name) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		Bitmap bitmap = BitmapFactory.decodeResource(
				ctx.getResources(),
				ctx.getResources().getIdentifier(name, "drawable",
						ctx.getPackageName()), options);
		return bitmap;
	}
}
